<script setup name="leftViews">
import { ref, computed } from 'vue'
import { ElMessage } from 'element-plus'
import {
	ternaryDatabase,
	binaryDatabase,
	elementOptions,
	formConfig,
	validators,
	getAllElementsBinary,
	getAllElementsTernary,
	getSecondElementsBinaryUniversal,
	getSecondElementsTernaryUniversal,
	getThirdElementsTernaryUniversal,
} from '../utils/config.js'

const props = defineProps({
	isLoading: Boolean,
	type: String, // 'binary' 或 'ternary'
})

const emit = defineEmits(['on-submit'])

const formRef = ref(null)

// 根据类型决定使用二元还是三元的表单字段
const isBinary = computed(() => props.type === 'binary')

// 线图计算模式
const lineMode = ref('temp_range') // 'temp_range' 或 'comp_range'

// 表单数据
const form = ref({
	// 通用字段
	firstElement: '',
	secondElement: '',
	thirdElement: '', // 仅三元使用
	pressure: 101325,

	// 固定成分根据温度范围模式
	tmin: 300,
	tmax: 800,
	tstep: 100,
	comp1: '', // 用户选择的元素1
	comp1_value: 0.02, // 元素1成分值
	comp2: '', // 用户选择的元素2 (仅三元使用)
	comp2_value: 0.03, // 元素2成分值 (仅三元使用)

	// 固定温度根据成分范围模式
	temp: 600,
	comp1_xmin: 0,
	comp1_xmax: 0.99,
	comp1_xcount: 100,
	comp2_xmin: 0,
	comp2_xmax: 0.99,
	comp2_xcount: 100,

	// 单位
	comp1_unit: '摩尔分数',
	comp2_unit: '摩尔分数',
})

// 计算属性 - 当前TDB文件
const currentTdbFile = computed(() => {
	if (isBinary.value) {
		if (!form.value.firstElement || !form.value.secondElement) return ''
		const matched = binaryDatabase.getMatchedCombination([
			form.value.firstElement,
			form.value.secondElement,
		])
		return matched?.dbFile || ''
	} else {
		if (
			!form.value.firstElement ||
			!form.value.secondElement ||
			!form.value.thirdElement
		)
			return ''
		const matched = ternaryDatabase.getMatchedConfiguration([
			form.value.firstElement,
			form.value.secondElement,
			form.value.thirdElement,
		])
		return matched?.dbFile || ''
	}
})

// 验证规则
const validationRules = computed(() => {
	const baseRules = {
		firstElement: [validators.required('请选择第一个元素')],
		secondElement: [validators.required('请选择第二个元素')],
		pressure: [validators.positiveNumber('压强必须大于等于0')],
		comp1: [validators.required('请选择元素1')],
		comp1_value: [validators.range01('元素1成分值必须在0到1之间')],
	}

	if (!isBinary.value) {
		baseRules.thirdElement = [validators.required('请选择第三个元素')]
		baseRules.comp2 = [validators.required('请选择元素2')]
		baseRules.comp2_value = [validators.range01('元素2成分值必须在0到1之间')]
		baseRules.comp2_xmin = [validators.range01('最小成分值必须在0到1之间')]
		baseRules.comp2_xmax = [
			validators.range01('最大成分值必须在0到1之间'),
			{
				validator: (rule, value, callback) => {
					if (
						value &&
						form.value.comp2_xmin &&
						value <= form.value.comp2_xmin
					) {
						callback(new Error('最大成分值必须大于最小成分值'))
					} else {
						callback()
					}
				},
				trigger: 'blur',
			},
		]
		baseRules.comp2_xcount = [validators.positiveStep('成分点数必须大于0')]
	}

	if (lineMode.value === 'temp_range') {
		return {
			...baseRules,
			tmin: [validators.positiveNumber('最小温度必须大于等于0')],
			tmax: [validators.positiveNumber('最大温度必须大于等于0')],
			tstep: [validators.positiveStep('步长必须大于0')],
		}
	} else {
		return {
			...baseRules,
			temp: [validators.positiveNumber('温度必须大于等于0')],
			comp1_xmin: [validators.range01('最小成分值必须在0到1之间')],
			comp1_xmax: [validators.range01('最大成分值必须在0到1之间')],
			comp1_xcount: [validators.positiveStep('成分点数必须大于0')],
		}
	}
})

// 计算属性 - 可选元素
const allElements = computed(() =>
	isBinary.value ? getAllElementsBinary() : getAllElementsTernary()
)
const availableSecondElements = computed(() =>
	isBinary.value
		? getSecondElementsBinaryUniversal(form.value.firstElement)
		: getSecondElementsTernaryUniversal(form.value.firstElement)
)
const availableThirdElements = computed(() =>
	getThirdElementsTernaryUniversal(
		form.value.firstElement,
		form.value.secondElement
	)
)

// 二元相图可选元素
const binaryElements = computed(() => {
	if (!form.value.firstElement || !form.value.secondElement) return []
	return [form.value.firstElement, form.value.secondElement]
})
const availableComp1Elements = computed(() => binaryElements.value)
const remainingBinaryElement = computed(() => {
	if (!form.value.comp1) return ''
	return binaryElements.value.find((el) => el !== form.value.comp1) || ''
})

// 三元相图可选元素
const ternaryElements = computed(() => {
	if (
		!form.value.firstElement ||
		!form.value.secondElement ||
		!form.value.thirdElement
	)
		return []
	return [
		form.value.firstElement,
		form.value.secondElement,
		form.value.thirdElement,
	]
})
const availableTernaryComp1Elements = computed(() =>
	ternaryElements.value.filter((el) => el !== form.value.comp2)
)
const availableTernaryComp2Elements = computed(() =>
	ternaryElements.value.filter((el) => el !== form.value.comp1)
)
const remainingTernaryElement = computed(() => {
	if (!form.value.comp1 || !form.value.comp2) return ''
	return (
		ternaryElements.value.find(
			(el) => el !== form.value.comp1 && el !== form.value.comp2
		) || ''
	)
})

// 元素选项
const elementOptions_computed = computed(() => {
	return isBinary.value ? elementOptions.binary : elementOptions.ternary
})

// 方法
const handleFirstElementChange = () => {
	form.value.secondElement = ''
	if (!isBinary.value) {
		form.value.thirdElement = ''
	}
}

const handleSecondElementChange = () => {
	if (!isBinary.value) {
		form.value.thirdElement = ''
	}
}

const resetForm = () => formRef.value?.resetFields()

const submitForm = async () => {
	if (!formRef.value) return
	try {
		await formRef.value.validate()

		// 构建基础数据
		const baseData = {
			elements: isBinary.value
				? `${form.value.firstElement},${form.value.secondElement}`
				: `${form.value.firstElement},${form.value.secondElement},${form.value.thirdElement}`,
			tdb: currentTdbFile.value,
			pressure: form.value.pressure,
		}

		// 根据模式添加特定字段
		let submitData = { ...baseData }

		if (lineMode.value === 'temp_range') {
			// 固定成分根据温度范围计算
			submitData = {
				...submitData,
				tmin: form.value.tmin,
				tmax: form.value.tmax,
				tstep: form.value.tstep,
				comp1: form.value.comp1,
				comp1_value: form.value.comp1_value,
			}

			// 三元图需要添加第二个元素的成分值
			if (!isBinary.value) {
				submitData.comp2 = form.value.comp2
				submitData.comp2_value = form.value.comp2_value
			}
		} else {
			// 固定温度根据成分范围计算
			submitData = {
				...submitData,
				temp: form.value.temp,
				comp1: form.value.comp1,
				comp1_xmin: form.value.comp1_xmin,
				comp1_xmax: form.value.comp1_xmax,
				comp1_xcount: form.value.comp1_xcount,
			}

			// 三元图需要添加第二个元素的固定成分值
			if (!isBinary.value) {
				submitData.comp2 = form.value.comp2
				submitData.comp2_value = form.value.comp2_value
				submitData.comp2_xmin = form.value.comp2_xmin
				submitData.comp2_xmax = form.value.comp2_xmax
				submitData.comp2_xcount = form.value.comp2_xcount
			}
		}

		emit('on-submit', {
			...submitData,
			type: props.type,
			model: 'line',
			mode: lineMode.value,
		})
	} catch (error) {
		ElMessage.error('表单验证失败，请检查输入！')
	}
}
</script>

<template>
	<div class="left-middle">
		<el-form
			ref="formRef"
			:model="form"
			:rules="validationRules"
			label-width="0px"
			class="form"
		>
			<!-- 元素选择 -->
			<div class="section-row element-select-section-row">
				<div class="section-col">
					<div class="section-header">第一个元素</div>
					<el-form-item prop="firstElement">
						<el-select
							v-model="form.firstElement"
							class="section-select"
							@change="handleFirstElementChange"
							clearable
							placeholder="选择元素"
						>
							<el-option
								v-for="item in allElements"
								:key="item"
								:label="item"
								:value="item"
							/>
						</el-select>
					</el-form-item>
				</div>
				<div class="section-col">
					<div class="section-header">第二个元素</div>
					<el-form-item prop="secondElement">
						<el-select
							v-model="form.secondElement"
							class="section-select"
							@change="handleSecondElementChange"
							:disabled="!form.firstElement"
							clearable
							placeholder="选择元素"
						>
							<el-option
								v-for="item in availableSecondElements"
								:key="item"
								:label="item"
								:value="item"
							/>
						</el-select>
					</el-form-item>
				</div>
				<div v-if="!isBinary" class="section-col">
					<div class="section-header">第三个元素</div>
					<el-form-item prop="thirdElement">
						<el-select
							v-model="form.thirdElement"
							class="section-select"
							:disabled="!form.firstElement || !form.secondElement"
							clearable
							placeholder="选择元素"
						>
							<el-option
								v-for="item in availableThirdElements"
								:key="item"
								:label="item"
								:value="item"
							/>
						</el-select>
					</el-form-item>
				</div>
				<div class="section-col">
					<div class="section-header">对应数据库</div>
					<el-form-item>
						<el-input
							v-model="currentTdbFile"
							class="section-input"
							readonly
							disabled
						/>
					</el-form-item>
				</div>
			</div>

			<hr />

			<div class="section-row element-select-section-row">
				<!-- 计算模式选择 -->
				<div class="section-col">
					<div class="section-header">计算模式</div>
					<el-select
						v-model="lineMode"
						class="section-select"
						placeholder="选择计算模式"
					>
						<el-option label="成分固定" value="temp_range" />
						<el-option label="温度固定" value="comp_range" />
					</el-select>
				</div>

				<!-- 压强 -->
				<div class="section-col">
					<div class="section-header">
						压强 <span class="section-title">压强值 (Pa)</span>
					</div>

					<el-form-item prop="pressure">
						<el-input
							v-model="form.pressure"
							v-positive-number
							class="section-input"
							placeholder="101325"
						/>
					</el-form-item>
				</div>
			</div>

			<hr />

			<!-- 元素选择区域（仿照图片风格，灰色标题，三列布局） -->

			<div class="section-row">
				<div class="section-col">
					<div class="section-header">主动改变元素</div>
				</div>
			</div>
			<div
				:class="[
					isBinary
						? 'section-row element-select-section-row'
						: 'section-row three-squares',
				]"
			>
				<div class="section-col">
					<div class="section-title">元素1</div>
					<el-form-item prop="comp1">
						<el-select
							v-model="form.comp1"
							class="section-select"
							:disabled="
								isBinary
									? !form.firstElement || !form.secondElement
									: !form.firstElement ||
										!form.secondElement ||
										!form.thirdElement
							"
							clearable
							:placeholder="'请选择'"
						>
							<el-option
								v-for="el in isBinary
									? availableComp1Elements
									: availableTernaryComp1Elements"
								:key="el"
								:label="el"
								:value="el"
							/>
						</el-select>
					</el-form-item>
				</div>
				<div class="section-col">
					<div class="section-title">元素2</div>
					<el-form-item v-if="!isBinary" prop="comp2">
						<el-select
							v-model="form.comp2"
							class="section-select"
							:disabled="
								!form.firstElement || !form.secondElement || !form.thirdElement
							"
							clearable
							placeholder="请选择"
						>
							<el-option
								v-for="el in availableTernaryComp2Elements"
								:key="el"
								:label="el"
								:value="el"
							/>
						</el-select>
					</el-form-item>
					<el-form-item v-else>
						<el-input
							:value="remainingBinaryElement"
							class="section-input"
							readonly
							disabled
							placeholder="自动计算"
						/>
					</el-form-item>
				</div>
				<div class="section-col" v-if="!isBinary">
					<div class="section-title">元素3</div>
					<el-form-item>
						<el-input
							class="section-input"
							:value="isBinary ? '' : remainingTernaryElement"
							readonly
							disabled
							placeholder="自动计算"
						/>
					</el-form-item>
				</div>
			</div>

			<hr />

			<!-- 元素1/2选择（只在温度范围模式下） -->
			<template v-if="lineMode === 'temp_range'">
				<!-- 原有温度范围输入结构 -->
				<div class="section-row">
					<div class="section-col">
						<div class="section-header">温度范围 (K)</div>
					</div>
				</div>
				<div class="section-row three-squares">
					<div class="section-col">
						<div class="section-title">最小温度</div>
						<el-form-item prop="tmin">
							<el-input
								v-model="form.tmin"
								v-positive-number
								class="section-input"
								placeholder="300"
							/>
						</el-form-item>
					</div>
					<div class="section-col">
						<div class="section-title">最大温度</div>
						<el-form-item prop="tmax">
							<el-input
								v-model="form.tmax"
								v-positive-number
								class="section-input"
								placeholder="800"
							/>
						</el-form-item>
					</div>
					<div class="section-col">
						<div class="section-title">步长</div>
						<el-form-item prop="tstep">
							<el-input
								v-model="form.tstep"
								v-positive-number
								class="section-input"
								placeholder="100"
							/>
						</el-form-item>
					</div>
				</div>

				<hr />

				<!-- 元素1成分值 -->
				<div class="section-row">
					<div class="section-col">
						<div class="section-header">
							元素1成分值 ({{ form.comp1 || '元素1' }})
						</div>
					</div>
				</div>
				<div class="section-row tow-squares">
					<div class="section-col">
						<div class="section-title">成分值</div>
						<el-form-item prop="comp1_value">
							<el-input
								v-model="form.comp1_value"
								v-positive-number="{ maxDecimals: 3, min: 0, max: 1 }"
								class="section-input"
								step="0.01"
								placeholder="0.02"
							/>
						</el-form-item>
					</div>
					<div class="section-col">
						<div class="section-title">单位</div>
						<el-form-item prop="comp1_unit">
							<el-select v-model="form.comp1_unit" class="section-select">
								<el-option
									v-for="item in formConfig.units.composition"
									:key="item"
									:label="item"
									:value="item"
								/>
							</el-select>
						</el-form-item>
					</div>
				</div>

				<!-- 三元时显示元素2成分值 -->
				<template v-if="!isBinary">
					<hr />
					<div class="section-row">
						<div class="section-col">
							<div class="section-header">
								元素2成分值 ({{ form.comp2 || '元素2' }})
							</div>
						</div>
					</div>
					<div class="section-row tow-squares">
						<div class="section-col">
							<div class="section-title">成分值</div>
							<el-form-item prop="comp2_value">
								<el-input
									v-model="form.comp2_value"
									v-positive-number="{ maxDecimals: 3, min: 0, max: 1 }"
									class="section-input"
									step="0.01"
									placeholder="0.03"
								/>
							</el-form-item>
						</div>
						<div class="section-col">
							<div class="section-title">单位</div>
							<el-form-item prop="comp2_unit">
								<el-select v-model="form.comp2_unit" class="section-select">
									<el-option
										v-for="item in formConfig.units.composition"
										:key="item"
										:label="item"
										:value="item"
									/>
								</el-select>
							</el-form-item>
						</div>
					</div>
				</template>
			</template>

			<!-- 固定温度根据成分范围模式 -->
			<template v-else>
				<!-- 原有温度范围输入结构 -->
				<div class="section-row">
					<div class="section-col">
						<div class="section-header">温度</div>
						<div class="section-title">温度值 (K)</div>
						<el-form-item prop="temp">
							<el-input
								v-model="form.temp"
								v-positive-number
								class="section-input"
								placeholder="600"
							/>
						</el-form-item>
					</div>
				</div>

				<hr />

				<!-- 元素1成分范围 -->
				<div class="section-row">
					<div class="section-col">
						<div class="section-header">
							元素1成分范围 ({{ form.comp1 || '元素1' }})
						</div>
					</div>
				</div>
				<div class="section-row three-squares">
					<div class="section-col">
						<div class="section-title">最小成分</div>
						<el-form-item prop="comp1_xmin">
							<el-input
								v-model="form.comp1_xmin"
								v-positive-number="{ maxDecimals: 3, min: 0, max: 1 }"
								class="section-input"
								step="0.01"
								placeholder="0"
							/>
						</el-form-item>
					</div>
					<div class="section-col">
						<div class="section-title">最大成分</div>
						<el-form-item prop="comp1_xmax">
							<el-input
								v-model="form.comp1_xmax"
								v-positive-number="{ maxDecimals: 3, min: 0, max: 1 }"
								class="section-input"
								step="0.01"
								placeholder="0.99"
							/>
						</el-form-item>
					</div>
					<div class="section-col">
						<div class="section-title">点数</div>
						<el-form-item prop="comp1_xcount">
							<el-input
								v-model="form.comp1_xcount"
								v-positive-number
								class="section-input"
								placeholder="100"
							/>
						</el-form-item>
					</div>
				</div>

				<!-- 三元时显示元素2成分范围 -->
				<template v-if="!isBinary">
					<hr />
					<div class="section-row">
						<div class="section-col">
							<div class="section-header">
								元素2成分范围 ({{ form.comp2 || '元素2' }})
							</div>
						</div>
					</div>
					<div class="section-row three-squares">
						<div class="section-col">
							<div class="section-title">最小成分</div>
							<el-form-item prop="comp2_xmin">
								<el-input
									v-model="form.comp2_xmin"
									v-positive-number="{ maxDecimals: 3, min: 0, max: 1 }"
									class="section-input"
									step="0.01"
									placeholder="0"
								/>
							</el-form-item>
						</div>
						<div class="section-col">
							<div class="section-title">最大成分</div>
							<el-form-item prop="comp2_xmax">
								<el-input
									v-model="form.comp2_xmax"
									v-positive-number="{ maxDecimals: 3, min: 0, max: 1 }"
									class="section-input"
									type="number"
									step="0.01"
									placeholder="0.99"
								/>
							</el-form-item>
						</div>
						<div class="section-col">
							<div class="section-title">点数</div>
							<el-form-item prop="comp2_xcount">
								<el-input
									v-model="form.comp2_xcount"
									v-positive-number
									class="section-input"
									type="number"
									placeholder="100"
								/>
							</el-form-item>
						</div>
					</div>
				</template>
			</template>
		</el-form>
	</div>
	<div class="left-bottom">
		<el-button @click="resetForm">重置</el-button>
		<el-button color="black" :loading="props.isLoading" @click="submitForm">
			计算
		</el-button>
	</div>
</template>

<style scoped lang="scss">
@import url('./index.scss');
</style>
